package io.github.talelin.latticy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.github.talelin.autoconfigure.exception.NotFoundException;
import io.github.talelin.latticy.common.LocalUser;
import io.github.talelin.latticy.dto.admin.ResetPasswordDTO;
import io.github.talelin.latticy.dto.feign.QueryUsersByIdsDTO;
import io.github.talelin.latticy.dto.omsuser.CreateOmsUserDTO;
import io.github.talelin.latticy.dto.omsuser.UpdateOmsUserDTO;
import io.github.talelin.latticy.dto.query.BasePageDTO;
import io.github.talelin.latticy.dto.user.RegisterDTO;
import io.github.talelin.latticy.model.OmsUserwareDO;
import io.github.talelin.latticy.model.UserDO;
import io.github.talelin.latticy.model.WmsOmsUserRelDO;
import io.github.talelin.latticy.mapper.WmsOmsUserRelMapper;
import io.github.talelin.latticy.service.GroupService;
import io.github.talelin.latticy.service.OmsUserwareService;
import io.github.talelin.latticy.service.feign.OpenFeignService;
import io.github.talelin.latticy.service.WmsOmsUserRelService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.github.talelin.latticy.vo.DeletedVO;
import io.github.talelin.latticy.vo.PageResponseVO;
import io.github.talelin.latticy.vo.UpdatedVO;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author generator@wulongbo
 * @since 2022-05-28
 */
@Service
public class WmsOmsUserRelServiceImpl extends ServiceImpl<WmsOmsUserRelMapper, WmsOmsUserRelDO> implements WmsOmsUserRelService {

    @Autowired
    private OpenFeignService openFeignService;

    @Autowired
    private GroupService groupService;

    @Autowired
    private OmsUserwareService omsUserwareService;

    @GlobalTransactional
    @Override
    public boolean createOmsUser(CreateOmsUserDTO dto) {
        // 默认注册为admin分组
        List<Integer> groupIds = openFeignService.getAdminGroupId();
        RegisterDTO registerDTO = new RegisterDTO();
        BeanUtils.copyProperties(dto, registerDTO);
        registerDTO.setGroupIds(groupIds);
        UserDO omsUserDO = openFeignService.registerOmsUser(registerDTO);
        UserDO userDO = LocalUser.getLocalUser();
        WmsOmsUserRelDO wmsOmsUserRelDO = new WmsOmsUserRelDO(userDO.getId(), omsUserDO.getId());
        this.baseMapper.insert(wmsOmsUserRelDO);
        List<OmsUserwareDO> list = dto.getCodes().parallelStream().map(code -> new OmsUserwareDO(omsUserDO.getId(), code)).collect(Collectors.toList());
        return omsUserwareService.saveBatch(list);
    }

    @Override
    public UserDO getUserById(Integer id) {
        return openFeignService.getOmsUserById(id);
    }

    @Override
    public List<UserDO> getUserOmsList() {
        return openFeignService.getOmsUserList();
    }

    @Override
    public PageResponseVO<UserDO> getUserOmsPage(BasePageDTO dto) {
        UserDO userDO = LocalUser.getLocalUser();
        boolean admin = groupService.checkIsRootByUserId(userDO.getId());
        if (admin) {
            return openFeignService.getOmsUsers(dto);
        }
        QueryWrapper<WmsOmsUserRelDO> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(WmsOmsUserRelDO::getWmsUserId, userDO.getId());
        List<WmsOmsUserRelDO> relList = this.baseMapper.selectList(wrapper);
        if (CollectionUtils.isEmpty(relList)) {
            return null;
        }
        List<Integer> omsUserIds = relList.parallelStream().map(WmsOmsUserRelDO::getOmsUserId).collect(Collectors.toList());
        QueryUsersByIdsDTO queryDTO = new QueryUsersByIdsDTO(dto, omsUserIds);
        return openFeignService.getOmsUsersByOmsUserIds(queryDTO);
    }

    @Override
    public UpdatedVO updateOmsUser(Integer id, UpdateOmsUserDTO dto) {
        return openFeignService.updateOmsUser(id, dto);
    }

    @Override
    public UpdatedVO changeUserPassword(Integer id, ResetPasswordDTO dto) {
        throwUserNotExistById(id);
        return openFeignService.changeOmsUserPassword(id, dto);
    }

    @Transactional
    @Override
    public boolean deleteOmsUser(Integer id) {
        UserDO userDO = LocalUser.getLocalUser();
        boolean admin = groupService.checkIsRootByUserId(userDO.getId());
        if (admin) {
            baseMapper.deleteLogicById(id);
        } else {
            baseMapper.deleteLogicByIdAndOmsUserId(userDO.getId(), id);
        }
        DeletedVO deletedVO = openFeignService.delOmsUserById(id);
        Optional.ofNullable(deletedVO).orElseThrow(() -> new NotFoundException(18307));
        return true;
    }

    private void throwUserNotExistById(Integer id) {
        UserDO omsUser = this.getUserById(id);
        if (omsUser == null) {
            throw new NotFoundException(10021);
        }
    }
}
